from django.db import connection, transaction

from app.decorator import jwt_auth
from app.my_exception import MyException
from app.service import goods_stock
from app.service.goods import query_goods_by_id
from app.service.goods_stock import get_stock_goods_list, count_stock_goods
from app.service.stock import handle_add_stock, save_goods_to_stock, del_goods_from_stock, add_up_stock_info
from libs.common import success, error, get_ts
from libs.form import RawJsonForm


@jwt_auth
def goods_list(request, auth):
    try:
        form = RawJsonForm(request.body)
        p = form.get_page()
        stock_status = form.get_int('status', default=None)
        if stock_status is None:
            stock_status = 0
        shop_id = auth.get('shop_id')
        cashier_id = auth.get('cashier_id')
        where_str = ' and sg.shop_id=%s and sg.cashier_id=%s'
        bind_arr = [shop_id, cashier_id]
        goods_id = form.get_int('goods_id')
        if goods_id > 0:
            where_str += ' and sg.goods_id=%s'
            bind_arr.append(goods_id)
        order_id = form.get_int('order_id')
        if order_id > 0:
            where_str += ' and sg.order_id=%s'
            bind_arr.append(order_id)
        total = count_stock_goods(stock_status, where_str, bind_arr)
        stock_goods_list = []
        if total > 0:
            stock_goods_list = get_stock_goods_list(stock_status, p, where_str, bind_arr)
        stock_info = add_up_stock_info(shop_id, cashier_id)
    except Exception as e:
        print(e)
        return error('获取库存列表异常')
    return success(stock_goods_list, total=total, page=p.page, size=p.size, **stock_info)


@jwt_auth
def update_goods(request, auth):
    form = RawJsonForm(request.body)
    goods_id = form.get_int('goods_id')
    input_amount = form.get_int('amount', None)
    input_amount_typ = type(input_amount)
    if input_amount_typ is int:
        if input_amount == -1:
            input_amount = None
        elif input_amount < 0:
            return error('添加库存数量错误')
    shop_id = auth.get('shop_id')
    cashier_id = auth.get('cashier_id')
    if goods_id == 0:
        return error('无效的商品ID')
    try:
        res = {
            'stock_id': 0,
            'opt_typ': '',
            'amount': 0,
            'subtotal': 0,
            'cost_price': 0,
        }
        if input_amount is None or input_amount > 0:
            db_goods_data = query_goods_by_id(shop_id, goods_id)
            db_goods_id = db_goods_data.get('id', 0)
            if db_goods_id == 0:
                return error('商品不存在')
            res, err = save_goods_to_stock(shop_id, cashier_id, goods_id, db_goods_data, input_amount)
            if err is not None:
                return error(err)
        else:
            err = del_goods_from_stock(shop_id, cashier_id, goods_id)
            if err is not None:
                return error(err)
            res['opt_typ'] = 'del'
    except Exception as e:
        print(e.args)
        return error('更新库存异常')
    return success(res)


@jwt_auth
def update_goods_v2(request, auth):
    form = RawJsonForm(request.body)
    shop_id = auth.get('shop_id')
    cashier_id = auth.get('cashier_id')
    post_args = form.get_list('')
    results = []
    err_num = 0
    suc_num = 0
    errs = []
    for i, post_data in enumerate(post_args):
        res, row_id, err = goods_stock.update_goods_stock(shop_id, cashier_id, post_data)
        results.append(res)
        if err is not None:
            errs.append(err)
            err_num += 1
        else:
            suc_num += 1
    if err_num > 0:
        return error('存在提交失败的数据', results=results, err_num=err_num, suc_num=suc_num, errs=errs)
    else:
        return success(results=results, err_num=err_num, suc_num=suc_num, errs=errs)


# 提交入库单
@jwt_auth
def submit_order(request, auth):
    form = RawJsonForm(request.body)
    shop_id = auth.get('shop_id')
    cursor = connection.cursor()
    try:
        with transaction.atomic():
            count_sql = 'select count(*) num from cs_stock_goods where shop_id=%s and `status`=0'
            bindings = [shop_id]
            cursor.execute(count_sql, bindings)
            row = cursor.fetchone()
            total = row[0]
            if total > 0:
                remark = form.get('remark')
                amount_paid = form.get('amount_paid')
                cashier_id = auth.get('cashier_id')
                now = get_ts()
                sql = 'insert into cs_stock_orders (shop_id,cashier_id,remark,amount_paid,`status`,created,updated) values (%s,%s,%s,%s,%s,%s,%s)'
                bindings = [shop_id, cashier_id, remark, amount_paid, 1, now, now]
                affected = cursor.execute(sql, bindings)
                if affected < 1:
                    raise MyException('提交入库单失败')
                order_id = cursor.lastrowid
                update_sql = 'update cs_stock_goods set order_id=%s,status=1 where shop_id=%s and `status`=0'
                bindings = [order_id, shop_id]
                cursor.execute(update_sql, bindings)
    except MyException as e:
        return error(str(e))
    except Exception as e:
        print(e)
        return error('提交进货单异常')
    finally:
        cursor.close()
    return success()


# 确认入库单
@jwt_auth
def confirm_order(request, auth):
    form = RawJsonForm(request.body)
    shop_id = auth.get('shop_id')
    order_id = form.get_int('id', None)
    cursor = connection.cursor()
    try:
        with transaction.atomic():
            if order_id is None:
                # 未提交入库单ID，将入库列表中未提交的商品入库
                count_sql = 'select count(*) num from cs_stock_goods where shop_id=%s and `status`=0'
                bindings = [shop_id]
                cursor.execute(count_sql, bindings)
                row = cursor.fetchone()
                total = row[0]
                if total > 0:
                    remark = form.get('remark')
                    amount_paid = form.get('amount_paid')
                    cashier_id = auth.get('cashier_id')
                    now = get_ts()
                    sql = 'insert into cs_stock_orders (shop_id,cashier_id,remark,amount_paid,`status`,created,updated) values (%s,%s,%s,%s,%s,%s,%s)'
                    bindings = [shop_id, cashier_id, remark, amount_paid, 100, now, now]
                    affected = cursor.execute(sql, bindings)
                    if affected < 1:
                        raise MyException('确认入库单失败')
                    order_id = cursor.lastrowid

                    sg_field_tup = ('id', 'goods_id', 'cost_price', 'amount', 'subtotal')
                    sg_field_str = ','.join(sg_field_tup)
                    sql = 'select {} from cs_stock_goods where shop_id=%s and `status`=0'.format(sg_field_str)
                    bindings = [shop_id]
                    cursor.execute(sql, bindings)
                    rows = cursor.fetchall()

                    handle_add_stock(cursor, order_id, shop_id, cashier_id, rows)
                else:
                    raise MyException('没有商品需要入库')
            else:
                count_sql = 'select cashier_id,deleted from cs_stock_orders where id=%s and shop_id=%s and status=1'
                bindings = [order_id, shop_id]
                cursor.execute(count_sql, bindings)
                row = cursor.fetchone()
                if row is not None:
                    (db_stock_order_cashier_id, db_stock_order_deleted) = row
                    if db_stock_order_deleted > 0:
                        raise MyException('入库单已删除')

                    sg_field_tup = ('id', 'goods_id', 'cost_price', 'amount', 'subtotal')
                    sg_field_str = ','.join(sg_field_tup)
                    sql = 'select {} from cs_stock_goods where order_id=%s and shop_id=%s'.format(sg_field_str)
                    bindings = [order_id, shop_id]
                    cursor.execute(sql, bindings)
                    rows = cursor.fetchall()
                    handle_add_stock(cursor, order_id, shop_id, db_stock_order_cashier_id, rows)
                    now = get_ts()
                    sql = 'update cs_stock_orders set status=100,updated=%s where id=%s and shop_id=%s'
                    bindings = [now, order_id, shop_id]
                    affected = cursor.execute(sql, bindings)
                    if affected < 1:
                        raise MyException('更新入库单失败')
                else:
                    raise MyException('入库单不存在')
    except MyException as e:
        return error(str(e))
    except Exception as e:
        print(e)
        return error('确认进货单异常')
    finally:
        cursor.close()
    return success()
